home *** CD-ROM | disk | FTP | other *** search
/ LiquidLibrary 2005 February / LiquidLibrary 2005 February - Disc 1.iso / pc / Portfolio Browser / Filters / PDF / LIB / gs_cidfn.ps < prev    next >
Text File  |  2003-01-03  |  12KB  |  382 lines

  1. %    Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is licensed to a single customer by Artifex Software Inc.
  3. % under the terms of a specific OEM agreement.
  4.  
  5. % $RCSfile$ $Revision$
  6. % ProcSet for implementing CIDFont and CIDMap resources.
  7. % When this is run, systemdict is still writable.
  8.  
  9. % ---------------- Defining CIDFont resources ---------------- %
  10.  
  11. % Define a CIDFont resource.  This is the defineresource implementation for
  12. % the CIDFont resource category.
  13.  
  14. /.checkfonttype {    % <cidfont> <fonttype> .checkfonttype <cidfont> <new?>
  15.   1 index /FID known {
  16.     1 index /FontType get ne {
  17.       /definefont cvx /invalidfont signalerror
  18.     } if false
  19.   } {
  20.     1 index /FontType 3 -1 roll put true
  21.   } ifelse
  22. } bind def
  23.  
  24. /.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse
  25. .cidfonttypes
  26.  
  27. 30 dict begin
  28.  
  29. % The key in .cidfonttypes is the CIDFontType value;
  30. % the value is a procedure that takes a font name and the CIDFont dictionary
  31. % and replaces the latter with a real font.
  32.  
  33. % ------ CIDFontType 0 (FontType 9) ------ %
  34.  
  35. % We add the following entries to the CIDFont dictionary, in addition to
  36. % the ones documented by Adobe:
  37. %    SubrCache - dictionary for caching Subr arrays
  38. % For CIDFonts where we read the data from disk incrementally:
  39. %    GlyphData is 0 (arbitrary)
  40. %    DataSource - a ReusableStreamDecode filter for the data
  41. % We also add a FID entry, and possibly a Subrs entry, to each element of
  42. % FDArray.
  43.  
  44. dup 0 {
  45.   9 .checkfonttype {
  46.     /CIDInit /ProcSet findresource begin
  47.     .completefont9
  48.     end
  49.   } if
  50.   1 index exch .buildfont9 exch pop
  51. } bind put
  52.  
  53. % Add entries to a new CIDFontType 0 font per documentation (FontMatrix)
  54. % or for .buildfont9 (FDArray.Private.Subrs).
  55. /.completefont9 {    % <cidfont0> .completefont9 <cidfont0>
  56.   currentglobal 3 1 roll dup gcheck setglobal
  57.   dup /FontMatrix known not {
  58.     dup /FontMatrix [0.001 0 0 0.001 0 0] put
  59.     dup /FDArray get {
  60.       /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop
  61.     } forall
  62.   } if
  63.   dup /FDArray get {
  64.         % Read the Subrs if necessary.
  65.     dup /Private get dup /Subrs known not {
  66.       dup /SubrCount .knownget {
  67.         % Stack: font Private SubrCount
  68.     currentglobal 3 1 roll 1 index gcheck setglobal
  69.     array 1 index /Subrs 3 -1 roll put
  70.         % Stack: font global Private
  71.     2 index begin begin .loadsubrs end end
  72.     setglobal
  73.       } {
  74.     pop
  75.       } ifelse readonly pop
  76.     } {
  77.       pop pop
  78.     } ifelse
  79.   } forall
  80.   3 -1 roll setglobal
  81. } bind def
  82.  
  83. % Read some Subrs for the current Type 1 subfont.
  84. % The subfont's Private dict is currentdict; the CIDFont itself is the
  85. % next dictionary on the stack.
  86. /.readsubrs {        % <Subrs> <start> .readsubrs <Subrs>
  87.   1 SubrCount 1 sub {
  88.     dup SDBytes mul SubrMapOffset add
  89.     dup SDBytes .readint exch SDBytes add SDBytes .readint
  90.     1 index sub string ReadString 2 index 3 1 roll put
  91.   } for
  92. } bind def
  93.  
  94. % Ensure that all the Subrs for the current Type 1 subfont are loaded.
  95. % The subfont's Private dict is currentdict; the CIDFont itself is the
  96. % next dictionary on the stack.
  97. /.loadsubrs {
  98.   Subrs length 0 ne {
  99.     SubrCache SubrMapOffset .knownget {
  100.         % We've already loaded some Subrs at this offset.
  101.         % Make sure we've got as many as we need.
  102.       dup length SubrCount lt {
  103.         % We need to load more.
  104.     SubrCount array exch 1 index copy length .readsubrs
  105.     SubrCache SubrMapOffset 2 index put
  106.       } if
  107.     } {
  108.         % We haven't loaded any Subrs at this offset yet.
  109.       SubrCount array 0 .readsubrs
  110.       SubrCache SubrMapOffset 2 index put
  111.     } ifelse
  112.     Subrs copy pop
  113.   } if
  114. } bind def
  115.  
  116. % ------ CIDFontType 1 (FontType 10) ------ %
  117.  
  118. dup 1 {
  119.   10 .checkfonttype pop
  120.   1 index exch .buildfont10 exch pop
  121. } bind put
  122.  
  123. % ------ CIDFontType 2 (FontType 11) ------ %
  124.  
  125. dup 2 {
  126.   11 .checkfonttype pop
  127.   1 index exch .buildfont11 exch pop
  128. } bind put
  129.  
  130. pop        % .cidfonttypes
  131.  
  132. % ---------------- Reading CIDFontType 0 files ---------------- %
  133.  
  134. /StartData {        % <(Binary)|(Hex)> <datalength> StartData -
  135.             %   (currentdict is CID font dict)
  136.         % If we're loading a resource file and the data format is
  137.         % binary, we can just save a pointer to the data and load it
  138.         % incrementally.
  139.   mark {
  140.         % Previous versions of this code made provisions for
  141.         % reading hex-encoded data incrementally.  Since hex data
  142.         % doesn't seem to be used in practice, we no longer bother.
  143.     2 index (Binary) ne { stop } if
  144.     currentfile .currentresourcefile ne { stop } if
  145.         % Hack: the pdfwrite driver relies on finalization to write
  146.         % out fonts.  However, the font may be finalized after the
  147.         % resource file, in which case the resource file will be
  148.         % closed.  So if the current output device is pdfwrite,
  149.         % don't use incremental loading.
  150.     currentdevice .devicename /pdfwrite eq { stop } if
  151.     currentfile fileposition
  152.   } .internalstopped {
  153.         % File is not positionable, or uses hex data.
  154.         % Load the data now.
  155.     cleartomark exch (Hex) eq
  156.       { { currentfile exch readhexstring pop } }
  157.       { { currentfile exch readstring pop } }
  158.     ifelse exch
  159.         % Stack: readproc length
  160.     dup 65400 le {
  161.         % readstring with a 0-length string causes a rangecheck,
  162.         % but a data length of 0 is allowed.
  163.       string dup () ne { 1 index exec } if
  164.     } {
  165.       mark 3 1 roll {
  166.         % Stack: mark str ... readproc length
  167.     dup 0 eq { pop exit } if
  168.     dup 65400 min dup string 3 index exec
  169.         % Stack: mark str ... readproc length newstrlen newstr
  170.     4 1 roll sub
  171.       } loop
  172.       counttomark 1 add 1 roll ]
  173.     } ifelse
  174.     /GlyphData exch def
  175.         % If we were reading hex data, skip past the >.
  176.     2 get { readhexstring } 0 get eq {
  177.       currentfile 0 (>) .subfiledecode dup flushfile closefile
  178.     } if
  179.   } {
  180.         % File is positionable and binary, just save a pointer.
  181.         % Stack: (Binary) length -mark- pos
  182.     /GlyphData 0 def
  183.     exch pop 3 -1 roll pop exch
  184.         % Stack: pos length
  185.     /DataSource currentfile 2 index () .subfiledecode true .reusablestream def
  186.     currentfile 3 1 roll add setfileposition
  187.   } ifelse
  188.   /SubrCache 10 dict def
  189.   CIDFontName currentdict /CIDFont defineresource pop
  190.   end            % CID font dict
  191.   end            % resource category dict
  192. } bind def
  193.  
  194. % Some Adobe fonts include the line
  195. %   /Setup /cid_Setup load def
  196. % This is apparently included only to prevent proper, conforming PostScript
  197. % interpreters (as opposed to ATM or a special Adobe font loader) from
  198. % loading the font, since Setup is not referenced anywhere else in the file.
  199. /cid_Setup { } def
  200.  
  201. currentdict end
  202.  
  203. % ---------------- Rendering ---------------- %
  204.  
  205. % ------ Generic ------ %
  206.  
  207. % Read a string at a given offset in a "file" (binary file or
  208. % GlyphData in RAM).
  209. /ReadString {        % <pos> <string> ReadString <string>
  210.   GlyphData 0 eq {
  211.     % Read from the file.
  212.     DataSource 3 -1 roll setfileposition
  213.     DataSource exch readstring pop
  214.   } {
  215.     % Read from a string or an array of strings.
  216.     GlyphData .stringsreadstring
  217.   } ifelse
  218. } bind def
  219. /.stringsreadstring    % <pos> <string> <strings> .stringsreadstring
  220.             %   <vmstring>
  221. { dup type /stringtype eq
  222.    { 3 1 roll length getinterval
  223.    }
  224.    {  {        % Stack: pos string glyphdata
  225.     dup 0 get length dup 4 index gt { exit } if
  226.     4 -1 roll exch sub 3 1 roll
  227.     dup length 1 sub 1 exch getinterval
  228.       }
  229.      loop
  230.         % Stack: pos string glyphdata glyphdata[0]length
  231.         % We know no request can span more than 2 strings.
  232.      3 index 3 index length add 1 index le
  233.       {        % Request fits in a single string: just return a substring.
  234.     pop 0 get 3 1 roll length getinterval
  235.       }
  236.       {        % Request spans 2 strings.  Copy the first part.
  237.     1 index 0 get 4 index 3 -1 roll 1 index sub getinterval
  238.     2 index copy
  239.         % Copy the second part.
  240.         % Stack: pos str glyphdata str1
  241.     length exch 1 get 0 3 index length
  242.     3 index sub getinterval 2 index 3 1 roll putinterval
  243.     exch pop
  244.       }
  245.      ifelse
  246.    }
  247.   ifelse
  248. } bind def
  249.  
  250. % Interpret a byte string as a (big-endian) integer.
  251. /.cvbsi            % <bytes> .cvbsi <int>
  252. { 0 exch { exch 8 bitshift add } forall
  253. } bind def
  254.  
  255. % Read an integer from binary data.
  256. /.readint        % <pos> <nbytes> .readint <int>
  257. { string ReadString .cvbsi
  258. } bind def
  259.  
  260. % ------ CIDFontType 0 ------ %
  261.  
  262. /.readglyphdata {
  263.   currentfont exch .type9mapcid
  264.   FDArray exch get exch
  265. } bind def
  266.  
  267. % BuildGlyph procedure for CIDFontType 0.
  268. % The name %Type9BuildGlyph is known to the interpreter.
  269. /.cid0buildstring 10 string def
  270. (%Type9BuildGlyph) cvn {    % <cidfont> <cid> %Type9BuildGlyph -
  271.   .currentglobal 3 1 roll 1 index gcheck .setglobal
  272.   1 index begin
  273.   dup .readglyphdata dup null eq {
  274.         % Substitute CID 0. **** WRONG ****
  275.     pop pop 0 .readglyphdata
  276.   } if
  277.         % Stack: cidfont cid subfont charstring
  278.   dup null eq { pop pop pop pop } {    %**** WRONG ****
  279.     4 -1 roll pop
  280.     3 1 roll exch dup 4 -1 roll 0 0 moveto
  281.     3 index /FontType get 2 eq { .type2execchar } { .type1execchar } ifelse
  282.   } ifelse    %**** WRONG ****
  283.   end
  284.   .setglobal
  285. } bind def
  286.  
  287. % ------ CIDFontType 2 ------ %
  288.  
  289. % BuildGlyph procedure for CIDFontType 2.
  290. % The name %Type11BuildGlyph is known to the interpreter.
  291. (%Type11BuildGlyph) cvn {    % <cidfont> <cid> %Type11BuildGlyph -
  292.         % We must be prepared for out-of-range CIDs.
  293.   2 copy { .type11mapcid } .internalstopped {
  294.     pop /CharStrings get /.notdef get
  295.   } if
  296.             % Stack: cidfont cid glyphindex
  297.   1 index exch .type42execchar
  298. } bind def
  299.  
  300. % ---------------- Define resources ---------------- %
  301.  
  302. languagelevel exch 2 .setlanguagelevel
  303.  
  304. % Define the CIDInit ProcSet resource.
  305. % The ProcSet dictionary is still on the stack.
  306.  
  307. % We might have loaded CMap support already.  However, Adobe's
  308. % protected font downloader defines a CIDInit ProcSet that will be
  309. % loaded from the filesystem later, so we must check specifically
  310. % for the ProcSet being defined in VM.
  311. /CIDInit /ProcSet 2 copy resourcestatus { pop 0 eq } { false } ifelse {
  312.   pop pop findresource dup length 4 index length add dict .copydict
  313.   4 -1 roll exch .copydict
  314. } {
  315.   3 -1 roll
  316. } ifelse exch defineresource pop
  317.  
  318. % Define the CIDFont resource category.
  319. % We break out .buildcidfont because it appears that at least for
  320. % Type 32 (CIDFontType 4) fonts, the font can be registered in the Font
  321. % category with only a CIDFontType and no FontType.
  322. /.buildcidfont {        % <name> <fontdict> .buildcidfont
  323.                 %   <name> <cidfont>
  324.   dup /CIDFontType get //.cidfonttypes exch get exec
  325. } odef
  326.  
  327. /CIDFont /Generic /Category findresource dup length dict .copydict
  328. dup /InstanceType /dicttype put
  329. dup /DefineResource {
  330.   .buildcidfont
  331.   /Generic /Category findresource /DefineResource get exec
  332. } put
  333. % CIDFonts may be defined in CFF OpenType files.
  334. % Check for this here.
  335. /.loadcidfontresource {
  336.   dup .ResourceFile {
  337.     {.loadfont} .execasresource
  338.   } {
  339.     dup /undefinedresource signalerror
  340.   } ifelse
  341. } bind def
  342. dup /.LoadResource {
  343.   currentglobal {
  344.     .loadcidfontresource
  345.   } {
  346.     true setglobal {.loadcidfontresource} stopped false setglobal {stop} if
  347.   } ifelse
  348. } bind put
  349.  
  350. /Category defineresource pop
  351.  
  352. % Add the new FontType resources.
  353.  
  354. 9 1 11 { dup /FontType defineresource pop } for
  355.  
  356. % Add the new FMapType resource.
  357.  
  358. 9 dup /FMapType defineresource pop
  359.  
  360. % Define the CIDMap resource category.
  361. % These aren't documented, but it's clear what they are for:
  362. % to give names to CIDMaps for CIDFontType 2 fonts.
  363.  
  364. /CIDMap /Generic /Category findresource dup length dict .copydict
  365. dup /.CheckResource {
  366.     % Allow a string, an array of strings, or (as of Adobe release 3011)
  367.     % a dictionary.
  368.   dup type dup dup /stringtype eq exch /dicttype eq or {
  369.     pop true
  370.   } {
  371.     dup /arraytype eq exch /packedarraytype eq or {
  372.       true exch { type /stringtype eq and } forall
  373.     } {
  374.       false
  375.     } ifelse
  376.   } ifelse
  377. } bind put
  378. /Category defineresource pop
  379.  
  380. .setlanguagelevel
  381.